Working With Video Channels
Sequence grabber components provide a number of functions that allow you to configure the grabber's video channels. This section describes these configuration functions, which you can use only with video channels. You can determine whether a channel has a visual representation by calling the
SGGetChannelInfo
function, which is described on
SGGetChannelInfo
. If you want to configure a sound channel, use the functions described in
"Working With Sound Channels,"
. If you want to configure general attributes of a channel, use the functions described in
"Working With Channel Characteristics,"
.
The
SGGetSrcVideoBounds
function allows you to determine the coordinates of the source video boundary rectangle. This rectangle defines the size of the source video image being captured by the video channel. You can use the
SGSetVideoRect
function to specify a part of the source video boundary rectangle to be captured by the channel. The
SGGetVideoRect
function allows you to determine the active source video rectangle.
Typically, the sequence grabber component uses the Image Compression Manager to compress the video data it captures. You can control many aspects of this image- compression process. Use the
SGSetVideoCompressorType
function to specify the type of image compressor to use. You can determine the type of image compressor currently in use by calling the
SGGetVideoCompressorType
function. You can specify a particular image compressor and set many image-compression parameters by calling the
SGSetVideoCompressor
function. You can determine which image compressor is being used and its parameter settings by calling the
SGGetVideoCompressor
function.
The channel components that supply video data to a sequence grabber component typically work with a video digitizer component (see the chapter "Video Digitizer Components" in this book for a complete description of video digitizer components). Sequence grabber components provide functions that allow you to work with a channel's video digitizer component. You can use the
SGGetVideoDigitizerComponent
function to determine which video digitizer component is supplying data to a specified channel component. You can set a channel's video digitizer by calling the
SGSetVideoDigitizerComponent
function. If you change any video digitizer settings by calling the video digitizer component directly, you should inform the sequence grabber component by calling the
SGVideoDigitizerChanged
function.
Some video source data may contain unacceptable levels of visual noise or artifacts. One technique for removing this noise is to capture the image and then reduce it in size. During the size reduction process, the noise can be filtered out. Sequence grabber components provide functions that allow you to filter the input video data. The
SGSetCompressBuffer
function sets a filter buffer for a video channel. The
SGGetCompressBuffer
function returns information about your filter buffer.
You can work with a video channel's frame rate by calling the
SGSetFrameRate
and
SGGetFrameRate
functions. You can control whether a channel uses an offscreen buffer by calling the
SGSetUseScreenBuffer
and
SGGetUseScreenBuffer
functions.
SGGetSrcVideoBounds
The
SGGetSrcVideoBounds
function allows you to determine the size of the source video boundary rectangle. This rectangle defines the size of the source video image. For video channel components that work with video digitizer components, this rectangle corresponds to the video digitizer's active source rectangle (see the chapter "Video Digitizer Components" in this book for more information).
pascal ComponentResult SGGetSrcVideoBounds (SGChannel c, Rect *r);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
r
-
Contains a pointer to a rectangle structure that is to receive information about the source video boundary rectangle.
RESULT CODE
paramErr
|
-50
|
Invalid parameter specified
|
SGSetVideoRect
The
SGSetVideoRect
function allows you to specify a part of the source video image that is to be captured by the sequence grabber component. This rectangle must reside within the boundaries of the source video boundary rectangle. You obtain the dimensions of the source video boundary rectangle by calling the
SGGetSrcVideoBounds
function, described in the previous section. If you do not use this function to set a source rectangle, the sequence grabber component captures the entire video image, as defined by the source video boundary rectangle.
pascal ComponentResult SGSetVideoRect
(SGChannel c, const Rect *r);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
r
-
Contains a pointer to the dimensions of the rectangle that defines the portion of the source video image to be captured. This rectangle must lie within the boundaries of the source video boundary rectangle, which you can obtain by calling the
SGGetSrcVideoBounds
function.
DESCRIPTION
For video channel components that receive their data from video digitizer components, this function sets the video digitizer component's digitizer rectangle. See the chapter "Video Digitizer Components" in this book for information about video digitizer components.
You cannot call this function during a record operation.
RESULT CODES
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
notEnoughMemoryToGrab
|
-9403
|
Insufficient memory for record operation
|
SGGetVideoRect
The
SGGetVideoRect
function allows you to determine the portion of the source video image that is to be captured. Use the
SGSetVideoRect
function, which is described in the previous section, to set the dimensions of this rectangle.
pascal ComponentResult SGGetVideoRect (SGChannel c, Rect *r);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
r
-
Contains a pointer to a rectangle structure that is to receive the dimensions of the rectangle that defines the portion of the source video image to be captured.
DESCRIPTION
If you have not set a source rectangle, the sequence grabber captures the entire source video image, as defined by the source video boundary rectangle.
SEE ALSO
You can obtain the dimensions of the source video boundary rectangle by calling the
SGGetSrcVideoBounds
function, described on
SGGetSrcVideoBounds
.
SGSetVideoCompressorType
The
SGSetVideoCompressorType
function allows you to specify the type of image compression to be applied to the captured video images.
pascal ComponentResult SGSetVideoCompressorType (SGChannel c,
OSType compressorType);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
compressorType
-
Specifies the type of image compression to use. The value of this parameter must correspond to one of the image compressor types supported by the Image Compression Manager. Currently, six
CodecType
values are provided by Apple. You should use the
GetCodecNameList
function to retrieve these names, so that your application can take advantage of new compressor types that may be added in the future. For each
CodecType
value in the following list, the corresponding compression method is also identified by its text string name.
|
Compressor type
|
Compressor name
|
|
'rpza'
|
video compressor
|
|
'jpeg'
|
photo compressor
|
|
'rle '
|
animation compressor
|
|
'raw '
|
raw compressor
|
|
'smc '
|
graphics compressor
|
|
'cvid'
|
compact video compressor
|
-
See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for information about valid compressor types. If this value is set to 0, the default compression type is selected.
DESCRIPTION
In addition, the
SGSetVideoCompressorType
function resets all image-compression parameters to their default values. You can then use the
SGSetVideoCompressor
function, described on
SGSetVideoCompressor
, to change the compression parameters.
SPECIAL CONSIDERATIONS
You cannot call the
SGSetVideoCompressorType
function during a record operation or after you have prepared the sequence grabber component for a record operation (by calling the
SGPrepare
function, described on
SGPrepare
).
RESULT CODES
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
notEnoughMemoryToGrab
|
-9403
|
Insufficient memory for record operation
|
deviceCantMeetRequest
|
-9408
|
Device cannot support grabber
|
SGGetVideoCompressorType
The
SGGetVideoCompressorType
function allows you to determine the type of image compression that is being applied to a channel's video data.
pascal ComponentResult SGGetVideoCompressorType (SGChannel c,
OSType *compressorType);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
compressorType
-
Contains a pointer to an
OSType
field that is to receive information about the type of image compression to use. The returned value must correspond to one of the image compressor types supported by the Image Compression Manager. Currently, six
CodecType
values are provided by Apple. You should use the
GetCodecNameList
function to retrieve these names, so that your application can take advantage of new compressor types that may be added in the future. For each
CodecType
value in the following list, the corresponding compression method is also identified by its text string name.
|
Compressor type
|
Compressor name
|
|
'rpza'
|
video compressor
|
|
'jpeg'
|
photo compressor
|
|
'rle '
|
animation compressor
|
|
'raw '
|
raw compressor
|
|
'smc '
|
graphics compressor
|
|
'cvid'
|
compact video compressor
|
-
See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for information about valid compressor types.
SEE ALSO
You can set the image-compression type by calling the
SGSetVideoCompressorType
function, which is described in the previous section.
SGSetVideoCompressor
The
SGSetVideoCompressor
function allows you to specify many of the parameters that control image compression of the video data captured by a video channel.
pascal ComponentResult SGSetVideoCompressor (SGChannel c,
short depth,
CompressorComponent compressor,
CodecQ spatialQuality,
CodecQ temporalQuality,
long keyFrameRate);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
depth
-
Specifies the depth at which the image is likely to be viewed. Image compressors may use this as an indication of the color or grayscale resolution of the compressed images. If you set this parameter to 0, the sequence grabber component determines the appropriate value for the source image. Values of 1, 2, 4, 8, 16, 24, and 32 indicate the number of bits per pixel for color images. Values of 33, 34, 36, and 40 indicate 1-bit, 2-bit, 4-bit, and 8-bit grayscale, respectively, for grayscale images. Your program can determine which depths are supported by a given compressor by examining the compressor information structure returned by the Image Compression Manager's
GetCodecInfo
function (see the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for more information on the
GetCodecInfo
function).
-
Set this parameter to 0 to leave the depth unchanged.
-
compressor
-
Specifies the image compressor identifier. Specify a particular compressor by setting this parameter to its compressor identifier. You can obtain this identifier from the Image Compression Manager's
GetCodecNameList
function. Set this parameter to 0 to leave the compressor unchanged.
-
spatialQuality
-
Specifies the desired compressed image quality. See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for valid values.
-
temporalQuality
-
Specifies the desired sequence temporal quality. This parameter governs the level of compression you desire with respect to information between successive frames in the sequence. Set this parameter to 0 to prevent the image compressor from applying temporal compression to the sequence. See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for other valid values.
-
keyFrameRate
-
Specifies the maximum number of frames allowed between key frames. Key frames provide points from which a temporally compressed sequence may be decompressed. Use this parameter to control the frequency at which the image compressor places key frames into the compressed sequence. For more information about key frames, see the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
.
-
The compressor determines the optimum placement for key frames based upon the amount of redundancy between adjacent images in the sequence. Consequently, the compressor may insert key frames more frequently than you have requested. However, the compressor will never place key frames less often than is indicated by the setting of the
keyFrameRate
parameter. The compressor ignores this parameter if you have not requested temporal compression (that is, you have set the
temporalQuality
parameter to 0).
DESCRIPTION
Typically, you are interested in setting only one or two of these parameters. You can call the
SGGetVideoCompressor
function to retrieve the values of all of the parameters, and you can then use that information to supply values for the parameters you do not wish to change.
SPECIAL CONSIDERATIONS
You may call this function during a record operation or after you have prepared the sequence grabber component for a record operation only if you set the
depth
and
compressor
parameters to 0. This allows you to work with the quality or key frame rate configuration while you are capturing a sequence.
RESULT CODES
paramErr
|
-50
|
Invalid parameter specified
|
c
antDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
notEnoughMemoryToGrab
|
-9403
|
Insufficient memory for record operation
|
deviceCantMeetRequest
|
-9408
|
Device cannot support grabber
|
SGGetVideoCompressor
The
SGGetVideoCompressor
function allows you to determine a channel's current image-compression parameters.
pascal ComponentResult SGGetVideoCompressor (SGChannel c,
short *depth,
compressorComponent *compressor,
CodecQ *spatialQuality,
CodecQ *temporalQuality,
long *keyFrameRate);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
depth
-
Contains a pointer to a field that is to receive the depth at which the image is likely to be viewed. Image compressors may use this as an indication of the color or grayscale resolution of the compressed images. If the value returned by this function is 0, the sequence grabber component determines the appropriate value for the source image. Values of 1, 2, 4, 8, 16, 24, and 32 indicate the number of bits per pixel for color images. Values of 33, 34, 36, and 40 indicate 1-bit, 2-bit, 4-bit, and 8-bit grayscale, respectively, for grayscale images. Your program can determine which depths are supported by a given compressor by examining the compressor information record (defined by the
CodecInfo
data type) returned by the Image Compression Manager's
GetCodecInfo
function (see the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for more information on the
GetCodecInfo
function).
-
If you are not interested in this information, set this parameter to
nil
.
-
compressor
-
Contains a pointer a field that is to receive an image compressor identifier. If you are not interested in this information, set this parameter to
nil
.
-
spatialQuality
-
Contains a pointer to a field that is to receive the desired compressed image quality. See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for valid values. If you are not interested in this information, set this parameter to
nil
.
-
temporalQuality
-
Contains a pointer to a field that is to receive the desired sequence temporal quality. This parameter governs the level of compression you desire with respect to information between successive frames in the sequence. If the returned value is set to 0, the image compressor is not performing temporal compression on the source video. See the chapter "Image Compression Manager" in
Inside Macintosh: QuickTime
for other valid values.
-
If you are not interested in this information, set this parameter to
nil
.
-
keyFrameRate
-
Contains a pointer to a field that is to receive the maximum number of frames allowed between key frames. Key frames provide points from which a temporally compressed sequence may be decompressed. This value controls the frequency at which the image compressor places key frames into the compressed sequence. The compressor determines the optimum placement for key frames based upon the amount of redundancy between adjacent images in the sequence. Consequently, the compressor may insert key frames more frequently than you have requested. However, the compressor will never place key frames less often than is indicated by the setting of the
keyFrameRate
parameter. The compressor ignores this value if you have not requested temporal compression (that is, you have set the
temporalQuality
parameter of the
SGSetVideoCompressor
function to 0).
-
If you are not interested in this information, set this parameter to
nil
.
SEE ALSO
You can set these parameters by calling the
SGSetVideoCompressor
function, which is described in the previous section.
SGSetVideoDigitizerComponent
The
SGSetVideoDigitizerComponent
function allows you to assign a video digitizer component to a video channel.
pascal ComponentResult SGSetVideoDigitizerComponent
(SGChannel c, ComponentInstance vdig);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
vdig
-
Contains a component instance that identifies a connection to a video digitizer component. The specified video channel component uses this video digitizer component to obtain its source video data. For more information about video digitizer components, see the chapter "Video Digitizer Components" in this book.
DESCRIPTION
Typically, the video channel component locates its own video digitizer component. Consequently, you may not need to use the
SGSetVideoDigitizerComponent
function.
SPECIAL CONSIDERATIONS
You cannot use the
SGSetVideoDigitizerComponent
function during a record operation. Many values are reinitialized as a result of changing digitizers.
RESULT CODE
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
SGGetVideoDigitizerComponent
The
SGGetVideoDigitizerComponent
function allows you to determine the video digitizer component that is providing source video to a video channel component. You can use this function to obtain access to the video digitizer component so that you can set its parameters, if you so desire. See the chapter "Video Digitizer Components" in this book for information about video digitizer components.
pascal ComponentInstance SGGetVideoDigitizerComponent
(SGChannel c);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
DESCRIPTION
The
SGGetVideoDigitizerComponent
function returns a component instance that identifies the connection between the video channel component and its video digitizer component. If the video channel component does not use a video digitizer component, this returned value is set to
nil
.
SPECIAL CONSIDERATIONS
If you change any video digitizer component parameters, be sure to notify the sequence grabber component by calling the
SGVideoDigitizerChanged
function, which is described in the next section. In addition, you should not change any video digitizer component parameters during a record operation.
SGVideoDigitizerChanged
The
SGVideoDigitizerChanged
function allows you to notify the sequence grabber component whenever you change the configuration of a video channel's video digitizer.
pascal ComponentResult SGVideoDigitizerChanged (SGChannel c);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
DESCRIPTION
The sequence grabber and its video channels maintain information about the configuration of any video digitizer components that are currently in use.
Important
It is very important to notify the sequence grabber of any configuration changes you make.
SPECIAL CONSIDERATIONS
You should not change the configuration of the video digitizer during a record operation.
SEE ALSO
You can obtain access to a video channel's video digitizer component by calling the
SGGetVideoDigitizerComponent
function, which is described in the previous section.
RESULT CODE
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
SGSetCompressBuffer
Some video source data may contain unacceptable levels of visual noise or artifacts. One technique for removing this noise is to capture the image and then reduce it in size. During the size reduction process, the noise can be filtered out.
The
SGSetCompressBuffer
function creates a filter buffer for a video channel. Logically, this buffer sits between the source video buffer and the destination rectangle you set with the
SGSetChannelBounds
function, described on
SGSetChannelBounds
. The filter buffer should be larger than the area enclosed by the destination rectangle.
pascal ComponentResult SGSetCompressBuffer (SGChannel c,
short depth,
const Rect *compressSize);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
depth
-
Specifies the pixel depth of the filter buffer. If you set this parameter to 0, the sequence grabber component uses the depth of the video buffer.
-
compressSize
-
Contains a pointer to the dimensions of the filter buffer. This buffer should be larger than the destination buffer. Set this parameter to
nil
, or set the coordinates of this rectangle to 0 (specifying an empty rectangle), to stop filtering the input source video data.
DESCRIPTION
If you establish a filter buffer for a channel, the sequence grabber component places the captured video image into the filter buffer, then copies the image into the destination buffer. This process may be too slow for some record operations, but can be useful during controlled record operations (where the source video can be read on a frame-by-frame basis). Be sure to call this function before you prepare the sequence grabber component for the record or playback operation.
Figure 2
demonstrates the process by which the
SGSetCompressBuffer
function creates a filter buffer for a video channel.
Figure 2
The effect of the
SGSetCompressBuffer
function
SEE ALSO
If you want to perform some more elaborate image filtering, you may define a transfer-frame function. See
"Video Channel Callback Functions,"
for more information about transfer-frame functions.
RESULT CODE
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
SGGetCompressBuffer
The
SGGetCompressBuffer
function returns information about the filter buffer you have established for a video channel.
pascal ComponentResult SGGetCompressBuffer (SGChannel c,
short *depth,
Rect *compressSize);
-
c
-
Specifies the reference that identifies the channel for this operation. You obtain this reference from the
SGNewChannel
function, described on
SGNewChannel
.
-
depth
-
Contains a pointer to a field that is to receive the pixel depth of the filter buffer. If the returned value is set to 0, the sequence grabber is not filtering the input video data.
-
compressSize
-
Contains a pointer to a rectangle structure that is to receive the dimensions of the filter buffer. If the sequence grabber is not filtering the input video data, it returns an empty rectangle (all coordinates set to 0).
SEE ALSO
You set a filter buffer by calling the
SGSetCompressBuffer
function, which is described in the previous section.
SGSetFrameRate
The
SGSetFrameRate
function allows you to specify a video channel's frame rate for recording.
pascal ComponentResult SGSetFrameRate (SGChannel c,
Fixed frameRate);
-
c
-
Identifies the channel for this operation. You provide your connection identifier. You connect to a channel component by calling the
SGNewChannel
or
SGNewChannelFromComponent
function, discussed on
SGNewChannel
and
SGNewChannelFromComponent
, respectively.
-
frameRate
-
Specifies the desired frame rate. Set this parameter to 0 to select the channel's default frame rate. Typically, this corresponds to the fastest rate that the channel can support.
DESCRIPTION
The
SGSetFrameRate
function allows you to control a video channel's frame rate. Note that the digitizing hardware may not be able to support the full rate you specify. If you specify too high a rate, the sequence grabber operates at the highest rate that it can support. Note that you may not call this function when you are recording.
RESULT CODES
paramErr
|
-50
|
Invalid parameter value
|
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
SEE ALSO
You can retrieve a channel's current frame rate by calling the
SGGetFrameRate
function, which is described next.
SGGetFrameRate
The
SGGetFrameRate
function allows you to retrieve a video channel's frame rate for recording.
pascal ComponentResult SGGetFrameRate (SGChannel c,
Fixed *frameRate);
-
c
-
Identifies the channel for this operation. You provide your connection identifier. You connect to a channel component by calling the
SGNewChannel
or
SGNewChannelFromComponent
function, discussed on
SGNewChannel
and
SGNewChannelFromComponent
, respectively.
-
frameRate
-
Contains a pointer to a field to receive the current frame rate. The sequence grabber returns the channel's current frame rate.
DESCRIPTION
The
SGGetFrameRate
function returns the channel's current rate. By default, the channel records at the fastest rate it can support. In this case, the channel sets the field referred to by the
frameRate
parameter to 0.
SEE ALSO
You can set a channel's frame rate by calling the
SGSetFrameRate
function, which is described in the previous section.
SGSetUseScreenBuffer
The
SGSetUseScreenBuffer
function allows you to control whether a video channel uses an offscreen buffer.
pascal ComponentResult SGSetUseScreenBuffer (SGChannel c,
Boolean useScreenBuffer);
-
c
-
Identifies the channel for this operation. You provide your connection identifier. You connect to a channel component by calling the
SGNewChannel
or
SGNewChannelFromComponent
function, discussed on
SGNewChannel
and
SGNewChannelFromComponent
, respectively.
-
useScreenBuffer
-
Indicates whether to use an offscreen buffer. If you set this parameter to
true
, the channel draws directly to the screen. If you set it to
false
, the channel may use an offscreen buffer. If the channel cannot work with offscreen buffers, it ignores this parameter.
DESCRIPTION
By default, video channels try to draw directly to the screen. The
SGSetUseScreenBuffer
function allows you to direct a video channel to draw to an offscreen buffer. If the channel cannot draw offscreen, it ignores this function. Note that you may not call this function when you are recording.
Directing a channel to draw offscreen may be useful if you are performing transformations on the data before displaying it (such as blending it with another graphical image).
RESULT CODES
paramErr
|
-50
|
Invalid parameter value
|
cantDoThatInCurrentMode
|
-9402
|
Request invalid in current mode
|
SEE ALSO
You can determine whether you have allowed a channel to draw offscreen by calling the
SGGetUseScreenBuffer
function, which is described next.
SGGetUseScreenBuffer
The
SGGetUseScreenBuffer
function allows you to determine whether a video channel is allowed to use an offscreen buffer.
pascal ComponentResult SGGetUseScreenBuffer (SGChannel c,
Boolean *useScreenBuffer);
-
c
-
Identifies the channel for this operation. You provide your connection identifier. You connect to a channel component by calling the
SGNewChannel
or
SGNewChannelFromComponent
function, discussed on
SGNewChannel
and
SGNewChannelFromComponent
, respectively.
-
useScreenBuffer
-
Contains a pointer to a Boolean value. The sequence grabber sets this field to reflect whether you have allowed the channel to draw offscreen. If this field is set to
true
, the channel draws directly to the screen. If it is set to
false
, the channel may use an offscreen buffer. If the channel cannot work with offscreen buffers, it ignores this value.
DESCRIPTION
By default, video channels draw directly to the screen. You can direct a channel to draw to an offscreen buffer by calling the
SGSetUseScreenBuffer
function. Channels that can work offscreen then allocate and draw to an offscreen buffer.
SEE ALSO
You can allow a channel to draw offscreen by calling the
SGSetUseScreenBuffer
function, which is described in the previous section.
© 1999 Apple Computer, Inc.Previous | Overview | Contents | Next